/**
 * 
 */
package com.study.reflect;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;

/**
 * @author Administrator
 * @date 2019年7月7日
 */
public class MethodTest {
	
	@MethodAnnotation(key="123", value="234")
	public String test() throws NullPointerException,ClassNotFoundException {
		return null;
	}

	public static void main(String[] args) throws Exception {
		Method method = MethodTest.class.getDeclaredMethod("test");
		System.out.println("getDeclaredMethod: " + method.getName());  //test
		
		AnnotatedType annotatedReturnType = method.getAnnotatedReturnType();
		System.out.println("getAnnotatedReturnType: " + annotatedReturnType.getType());  //class java.lang.String		
		//getAnnotatedReturnType(): 返回一个AnnotatedType对象，该对象表示使用一个类型来指定由该可执行文件表示的方法/构造函数的返回类型
		
		AnnotatedType[] annotatedExceptionTypes = method.getAnnotatedExceptionTypes();
		for(AnnotatedType a : annotatedExceptionTypes) {
			System.out.println("annotatedExceptionTypes: " + a.getType()); //class java.lang.NullPointerException
		}
		//getAnnotatedExceptionTypes(): 返回一个AnnotatedType对象数组，这些对象表示使用类型来指定由该可执行文件表示的方法/构造函数声明的异常
		
		AnnotatedType annotatedReceiverType = method.getAnnotatedReceiverType();
		System.out.println("annotatedReceiverType: " + annotatedReceiverType.getType()); //class com.study.reflect.MethodTest
		//getAnnotatedReceiverType():返回一个AnnotatedType对象，该对象表示使用一个类型来指定该可执行对象表示的方法/构造函数的接收者类型
		
		MethodAnnotation annotation = method.getAnnotation(MethodAnnotation.class);
		System.out.println("getAnnotation: " + annotation); //@com.study.reflect.MethodAnnotation(key=123, value=234)
		//getAnnotation 如果该方法对象存在指定类型的注解，则返回该注解
		//getDeclaredAnnotation 如果该方法对象存在指定类型的注解，则返回该注解
		
		//getAnnotations() 返回该方法对象上的所有注解
		Annotation[] annotations = method.getAnnotations();
		for(Annotation a: annotations){
			System.out.println("getAnnotations: " + a);
		}
		
		//isAnnotationPresent(Class<? extends Annotation> annotationClass)
		//如果该方法对象上有指定类型的注解，则返回true，否则为false
		boolean annotationPresent = method.isAnnotationPresent(MethodAnnotation.class);
		System.out.println("isAnnotationPresent: " + annotationPresent);
		
		method.setAccessible(false);
		System.out.println("after setAccessible: " + method.getModifiers());
		//1 表示 public
	
	}
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MethodAnnotation {
	String key();
	String value();
}
